# 编译器检测 操作系统检测 C++标准版本设置

# 默认开启后对性能评估有巨大影响，他的性能下降并不是全面下降，跟内存访问相关。开启检查后性能测试结果不具备参考价值
MESSAGE(STATUS "[cmake_util] import init_default_env.cmake")
MESSAGE(STATUS "xcmake: set default env")
OPTION(XCMAKE_ENABLE_ASAN "default is enable ASAN for memory leak and exception" OFF)

################################################### 公共变量
# 设置当前 文件所在目录（直接使用） 直接使用CMAKE_CURRENT_SOURCE_DIR，当当前文件不再项目根目录时会出现bug，需要使用CMAKE_CURRENT_LIST_FILE
get_filename_component(XCMAKE_UTIL_DIR "${CMAKE_CURRENT_LIST_FILE}" DIRECTORY)
###################################################

################################################### 编译器
SET(XCMAKE_COMPILER_MSVC FALSE)
SET(XCMAKE_COMPILER_GCC FALSE)
SET(XCMAKE_COMPILER_CLANG FALSE)
###################################################
################################################### 目标操作系统
SET(XCMAKE_TARGET_OS_WIN FALSE)
SET(XCMAKE_TARGET_OS_LINUX FALSE)
SET(XCMAKE_TARGET_OS_MAC FALSE)
###################################################

################################################################## 编译器检测
IF(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
    SET(XCMAKE_COMPILER_MSVC TRUE)
    MESSAGE(STATUS "xcmake: compiler MSVC")
ELSEIF(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
    SET(XCMAKE_COMPILER_GCC TRUE)
    MESSAGE(STATUS "xcmake: compiler GCC")
ELSEIF((CMAKE_CXX_COMPILER_ID STREQUAL "CLANG") OR (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang"))
    SET(XCMAKE_COMPILER_CLANG TRUE)
    MESSAGE(STATUS "xcmake: compiler CLANG")
ELSE()
    MESSAGE(STATUS "xcmake: unknown compiler: " ${CMAKE_CXX_COMPILER_ID})
ENDIF()
##################################################################
################################################################## 目标操作系统检测
#MESSAGE(STATUS "xcmake: " ${CMAKE_SYSTEM_NAME})
IF(CMAKE_SYSTEM_NAME MATCHES "Linux")
    SET(XCMAKE_TARGET_OS_LINUX TRUE)
    MESSAGE(STATUS "xcmake: target os: LINUX")
ELSEIF(CMAKE_SYSTEM_NAME MATCHES "Windows")
    SET(XCMAKE_TARGET_OS_WIN TRUE)
    MESSAGE(STATUS "xcmake: target os: WIN")
ELSEIF((CMAKE_SYSTEM_NAME MATCHES "Apple") OR (CMAKE_SYSTEM_NAME MATCHES "Darwin"))
    SET(XCMAKE_TARGET_OS_MAC TRUE)
    MESSAGE(STATUS "xcmake: target os: MAC")
ELSE()
    MESSAGE(STATUS "xcmake: unknown target os: " ${CMAKE_SYSTEM_NAME})
ENDIF()
##################################################################

##################################################################
# MSVC特殊处理
IF(XCMAKE_COMPILER_MSVC)
    MESSAGE(STATUS "xcmake: setup default config for MSVC")
    #启用虚拟目录(vs)
    MESSAGE(STATUS "xcmake: enable vs virtual folders")
    SET_PROPERTY(GLOBAL PROPERTY USE_FOLDERS ON)
    #强制源码格式为utf-8
    MESSAGE(STATUS "xcmake: build on windows-msvc: /utf-8")
    SET(CMAKE_C_FLAGS   "${CMAKE_C_FLAGS}   /utf-8")
    SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /utf-8")
    #关闭DLL导出接口使用STL的告警
    MESSAGE(STATUS "xcmake: build on windows-msvc: /wd\"4251\"")
    SET(CMAKE_C_FLAGS   "${CMAKE_C_FLAGS}   /wd\"4251\"")
    SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd\"4251\"")
    #添加windows特定的宏
    MESSAGE(STATUS "xcmake: build on windows-msvc: -DWIN32_WINNT")
    add_definitions(-DWIN32_WINNT)
    #设置c++标准宏定义__cplusplus生效
    MESSAGE(STATUS "xcmake: build on windows-msvc: /Zc:__cplusplus")
    SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Zc:__cplusplus")
ELSEIF(XCMAKE_COMPILER_GCC)
    MESSAGE(STATUS "xcmake: setup default config for gcc")
    MESSAGE(STATUS "xcmake: -fPIC")
    SET(CMAKE_C_FLAGS   "${CMAKE_C_FLAGS}   -fPIC")
    SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
    MESSAGE(STATUS "xcmake: disable optimization when build type is RELWITHDEBINFO: -O0")
    set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -O0 -g")
    set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -O0 -g")
    # ASAN配置
    # -fsanitize=address #开启地址越界检查功能
    # -fno-omit-frame-pointer #开启后，可以出界更详细的错误信息(到更容易理解stack trace)可选择-O1或者更高的优化级别编译
    # -fsanitize=leak #开启内存泄露检查功能
    # -ggdb #方便调试(生成gdb专用调试信息类似-g -g123这种参数)
    # -fsanitize-recover=all no-sanitize-recover=all  no前缀表示检测到错误立刻停下来，无no表示继续运行
    # export ASAN_OPTIONS=abort_on_error=1:disable_coredump=0:unmap_shadow_on_exit=1 通过环境变量传参可以控制直接出dump等行为
    #set(CMAKE_CXX_FLAGS	" -std=c++11 -fsanitize=address -fsanitize-recover=all  -fsanitize=leak")
    IF(${XCMAKE_ENABLE_ASAN})
        message("xcmake: enable ascan")
        add_compile_options(-fsanitize=address -fno-sanitize-recover=all -fsanitize=leak)
        add_link_options(-fsanitize=address -fno-sanitize-recover=all -fsanitize=leak)
    ENDIF()
ENDIF()
##################################################################


##################################################################
# 设置C++标准
SET(CMAKE_CXX_STANDARD 17)
MESSAGE(STATUS "xcmake: set cpp standard to: C++17")
# 设置C标准
SET(CMAKE_C_STANDARD 11)
MESSAGE(STATUS "xcmake: set c standard to: C11")
##################################################################
##################################################################
# 设置默认路径
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin)
SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/lib)
SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/lib)
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_SOURCE_DIR}/bin)
SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG ${CMAKE_SOURCE_DIR}/lib)
SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${CMAKE_SOURCE_DIR}/lib)
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_SOURCE_DIR}/bin)
SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE ${CMAKE_SOURCE_DIR}/lib)
SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${CMAKE_SOURCE_DIR}/lib)
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO ${CMAKE_SOURCE_DIR}/bin)
SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELWITHDEBINFO ${CMAKE_SOURCE_DIR}/lib)
SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELWITHDEBINFO ${CMAKE_SOURCE_DIR}/lib)
##################################################################
# CMAKE_DEBUG_POSTFIX FRAMEWORK_MULTI_CONFIG_POSTFIX_<CONFIG>

##################################################################
# 导入xthrid_part的cmake
get_filename_component(XTHIRD_PART_XCMAKE_DIR ${XCMAKE_UTIL_DIR}/../../xthird_part/xcmake ABSOLUTE)
LIST(APPEND CMAKE_PREFIX_PATH ${XTHIRD_PART_XCMAKE_DIR})
# LIST(APPEND CMAKE_MODULE_PATH ${XTHIRD_PART_XCMAKE_DIR}) 
MESSAGE(STATUS "xcmake: add xthird_part xcmake: xcmake=" ${XTHIRD_PART_XCMAKE_DIR})
MESSAGE(STATUS "xcmake: laster CMAKE_PREFIX_PATH=" ${CMAKE_PREFIX_PATH})
# MESSAGE(STATUS "xcmake: laster CMAKE_MODULE_PATH=" ${CMAKE_MODULE_PATH})

#include(${XTHIRD_PART_XCMAKE_DIR}/xboost-config.cmake)
##################################################################

# 还没有找到和cmake配合cppcheck的用法
# find_program(CMAKE_C_CPPCHECK cppcheck)
# if(CMAKE_C_CPPCHECK)
#     list(APPEND CMAKE_CXX_FLAGS "-DCMAKE_C_CPPCHECK=${CMAKE_C_CPPCHECK}")
# endif()